home *** CD-ROM | disk | FTP | other *** search
- /* Copyright 1990 by Christopher A. Wichura.
- See file GIFMachine.doc for full description of rights.
- */
-
- #include "GIFMachine.h"
-
- extern struct GIFdescriptor gdesc;
- EXTERNBITPLANE;
-
- static struct ImageDesc idesc;
- extern struct RGB GlobalColourTable[256];
- static struct RGB LocalColourTable[256];
- extern ULONG ImageNumber;
-
- extern char *AbortMsg;
-
- static UWORD Xpos, Ypos;
- static BOOL interleave;
-
- static UBYTE LeaveStep[5] = {1, 8, 8, 4, 2};
- static UBYTE LeaveFirst[5] = {0, 0, 4, 2, 1};
-
- /* some variables used by the decompressor */
- static int ReadError;
- static UBYTE CodeSize;
- static int EOFCode;
- static UBYTE ReadMask;
- static int CompDataPointer;
- static int CompDataCount;
- static UBYTE CompData[256];
-
- /* tables used by the decompressor */
- static UWORD Prefix[4096];
- static UBYTE Suffix[4096];
- static UBYTE OutCode[1025];
-
- extern BOOL DisplayCounts;
-
- BOOL DoImage(BPTR fh)
- {
- register int index;
- register int colours;
- int Code;
-
- MyPrintf("...Image #%ld encountered.\n", ImageNumber++);
-
- if (FRead(fh, (char *)&idesc, 1, 9) != 9) {
- PutStr("......Error reading image descriptor.\n");
- return TRUE;
- }
-
- FlipWord(&idesc.id_Left);
- FlipWord(&idesc.id_Top);
- FlipWord(&idesc.id_Width);
- FlipWord(&idesc.id_Height);
-
- interleave = idesc.id_Info & 1L << 6;
- if (interleave)
- interleave = 1;
-
- MyPrintf("......Xpos from %ld to %ld, Ypos from %ld to %ld, %sinterlaced.\n",
- idesc.id_Left, idesc.id_Left + idesc.id_Width - 1,
- idesc.id_Top, idesc.id_Top + idesc.id_Height - 1,
- interleave ? "" : "not ");
-
- if (idesc.id_Info & 1L << 7) {
- colours = 1L << ((idesc.id_Info & 7) + 1);
- MyPrintf("......Local colour map contains %ld entries.\n", colours);
-
- for (index = 0; index < colours; index++) {
- if (FRead(fh, &LocalColourTable[index], 1, 3) != 3) {
- MyPrintf("......Error reading local colour #%ld.\n",
- index);
- return TRUE;
- }
- }
- } else {
- colours = 1L << ((gdesc.gd_ColInfo & 7) + 1);
- CopyMem((char *)GlobalColourTable, (char *)LocalColourTable,
- sizeof(LocalColourTable));
- }
-
- Xpos = Ypos = 0;
-
- /* now we are ready to read the image in so do it! */
-
- {
- int MaxCode, ClearCode, CurCode,
- OldCode, InCode, FreeCode;
- int OutCount;
- int FirstFree;
- UBYTE InitCodeSize, FinChar, BitMask;
-
- if (DisplayCounts)
- MyPrintf("......Decompressing line number %5ld", Ypos);
- else
- PutStr("......Decompressing");
- Flush(Output());
-
- /* get the codesize and do general setup for decompression */
- if ((CodeSize = FGetC(fh)) == -1) {
- PutStr("\n......I/O Error during decompression.\n");
- return TRUE;
- }
-
- ClearCode = 1L << CodeSize;
- EOFCode = ClearCode + 1;
- FreeCode = FirstFree = ClearCode + 2;
-
- CodeSize++; /* per GIF spec */
- InitCodeSize = CodeSize;
- MaxCode = 1L << CodeSize;
- ReadError = ReadMask = OutCount = 0;
- CompDataPointer = CompDataCount = 0;
-
- BitMask = colours - 1;
-
- Code = ReadCode(fh);
- while (Code != EOFCode) {
- if (ReadError)
- return TRUE;
-
- if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
- MyPrintf("\n%s", AbortMsg);
- MyExit(ABORTEXITVAL);
- }
-
- if (Code == ClearCode) {
- CodeSize = InitCodeSize;
- MaxCode = 1L << CodeSize;
- FreeCode = FirstFree;
- FinChar = CurCode = OldCode = Code = ReadCode(fh);
- AddPixel(FinChar);
- } else {
- CurCode = InCode = Code;
-
- if (CurCode >= FreeCode) {
- CurCode = OldCode;
- OutCode[OutCount++] = FinChar;
- }
-
- while (CurCode > BitMask) {
- if (OutCount > 1024) {
- PutStr("\n......Corrupt GIF file (OutCount)\n");
- return TRUE;
- }
-
- OutCode[OutCount++] = Suffix[CurCode];
- CurCode = Prefix[CurCode];
- }
-
- FinChar = CurCode;
- AddPixel(FinChar);
-
- for (index = OutCount - 1; index >= 0; index--)
- AddPixel(OutCode[index]);
- OutCount = 0;
-
- Prefix[FreeCode] = OldCode;
- Suffix[FreeCode] = FinChar;
- OldCode = InCode;
-
- if (++FreeCode >= MaxCode) {
- if (CodeSize < 12) {
- CodeSize++;
- MaxCode <<= 1;
- }
- }
- }
-
- Code = ReadCode(fh);
- }
- }
-
- if ((Code = FGetC(fh)) == -1)
- return TRUE;
-
- /* done decompressing. Erase decompressing message and exit */
- MyPrintf("\x1B[%ldD\x1B[Ked.\n", (DisplayCounts ? 21 : 3));
-
- if (Code != 0) {
- PutStr("......Warning: Unaligned packet.\n");
- UnGetC(fh, Code);
- }
-
- return FALSE;
- }
-
- static UBYTE ByteBuf;
-
- int ReadCode(BPTR fh)
- {
- register int temp;
- register int DstMasked;
- register int DstMask;
- register LONG size;
-
- temp = 0;
- DstMasked = 1L << CodeSize;
- for (DstMask = 1; DstMask != DstMasked; DstMask <<= 1) {
- if (!ReadMask) {
- if (CompDataPointer == CompDataCount) {
- if ((size = FGetC(fh)) == -1) {
- PutStr("\n......I/O Error during decompression.\n");
- ReadError = 1;
- return EOFCode;
- }
-
- if (FRead(fh, (char *)CompData, 1, size) != size) {
- PutStr("\n......I/O Error during decompression.\n");
- ReadError = 1;
- return EOFCode;
- }
-
- CompDataCount = size;
- CompDataPointer = 0;
- }
-
- ReadMask = 1;
- ByteBuf = CompData[CompDataPointer++];
- }
-
- if (ByteBuf & ReadMask)
- temp |= DstMask;
-
- ReadMask <<= 1;
- }
-
- return temp;
- }
-
- void AddPixel(UBYTE index)
- {
- register UWORD XStore;
- register UWORD YStore;
-
- XStore = Xpos + idesc.id_Left;
- YStore = Ypos + idesc.id_Top;
-
- BitPlane[YStore][XStore] = LocalColourTable[index];
-
- if (++Xpos == idesc.id_Width) {
- Xpos = 0;
- Ypos += LeaveStep[interleave];
- if (Ypos >= idesc.id_Height)
- Ypos = LeaveFirst[++interleave];
-
- if (DisplayCounts)
- MyPrintf("\x1B[5D%5ld", Ypos + idesc.id_Top);
- }
- }
-